Devoir de Techniques de visualisation des données

MOISE EHIMIGAYE SENGHOR

UE : Visualisation de données

In [1]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns 
import missingno as msno
import sweetviz as sv
import datetime
import calendar
import plotly.express as px
from math import *
from matplotlib.ticker import FuncFormatter
from sklearn.datasets import load_iris
from matplotlib.patches import Patch  
from matplotlib.lines import Line2D  
import matplotlib.colors as mcolors 
from matplotlib import cm
from matplotlib.colors import LinearSegmentedColormap
from matplotlib.ticker import LogLocator
from matplotlib import gridspec
import warnings
warnings.filterwarnings("ignore")

Exercices d’application :¶

Exercice 1 :¶

Analysons et explorons les données :¶

In [2]:
#Importons les données :
these = pd.read_csv("PhD_v3.csv", sep = ',', low_memory=False , encoding='utf-8')
In [3]:
these.head()
Out[3]:
Unnamed: 0 Auteur Identifiant auteur Titre Directeur de these Directeur de these (nom prenom) Identifiant directeur Etablissement de soutenance Identifiant etablissement Discipline ... Year Langue de la these Identifiant de la these Accessible en ligne Publication dans theses.fr Mise a jour dans theses.fr Discipline_prédi Genre etablissement_rec Langue_rec
0 0 Saeed Al marri NaN Le credit documentaire et l'onopposabilite des... Philippe Delebecque Delebecque Philippe 29561248 Paris 1 27361802 Driot prive ... NaN na s69480 non 26-01-12 26-01-12 Droit et Science Politique male Université Paris 1 - Panthéon Sorbonne NaN
1 1 Andrea Ramazzotti 174423705 Application de la PGD a la resolution de probl... Jean-Claude Grandidier,Marianne Beringhier Grandidier Jean-Claude,Beringhier Marianne 715,441,511 Chasseneuil-du-Poitou, Ecole nationale superie... 28024400 Mecanique des solides, des materiaux, des stru... ... NaN na s98826 non 22-11-13 22-11-13 Materiaux, Milieux et Chimie female École nationale supérieure de mécanique et d'a... NaN
2 2 OLIVIER BODENREIDER NaN Conception d'un outil informatique d'etude des... Francois Kohler Kohler Francois 57030758 Nancy 1 NaN Medecine ... 1993.0 fr 1993NAN19006 non 24-05-13 17-11-12 Medecine male Université de Lorraine Français
3 3 Emmanuel Porte NaN Socio-histoire des politiques publiques en mat... Gilles Pollet Pollet Gilles na Lyon 2 02640334X Science politique ... NaN na s88867 non 12-07-13 12-01-16 Droit et Science Politique male Université Lumière - Lyon 2 NaN
4 4 Arthur Devriendt NaN LES TECHNOLOGIES DE L'INFORMATION ET DE LA COM... Gabriel Dupuy Dupuy Gabriel na Paris 1 27361802 Geographie ... NaN na s89663 non 13-07-13 12-07-13 SHS male Université Paris 1 - Panthéon Sorbonne NaN

5 rows × 23 columns

In [4]:
these.shape
Out[4]:
(448047, 23)
In [5]:
rapport = sv.analyze(these)
rapport.show_html('rapport_these.html')
                                             |          | [  0%]   00:00 -> (? left)
Report rapport_these.html was generated! NOTEBOOK/COLAB USERS: the web browser MAY not pop up, regardless, the report IS saved in your notebook/colab files.
In [6]:
these.info() # un petit recap des differentes variables de notre jeu de données
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 448047 entries, 0 to 448046
Data columns (total 23 columns):
 #   Column                                    Non-Null Count   Dtype  
---  ------                                    --------------   -----  
 0   Unnamed: 0                                448047 non-null  int64  
 1   Auteur                                    448047 non-null  object 
 2   Identifiant auteur                        317700 non-null  object 
 3   Titre                                     448040 non-null  object 
 4   Directeur de these                        448034 non-null  object 
 5   Directeur de these (nom prenom)           448034 non-null  object 
 6   Identifiant directeur                     448047 non-null  object 
 7   Etablissement de soutenance               448046 non-null  object 
 8   Identifiant etablissement                 430965 non-null  object 
 9   Discipline                                448047 non-null  object 
 10  Statut                                    448047 non-null  object 
 11  Date de premiere inscription en doctorat  64331 non-null   object 
 12  Date de soutenance                        390961 non-null  object 
 13  Year                                      390961 non-null  float64
 14  Langue de la these                        448047 non-null  object 
 15  Identifiant de la these                   448047 non-null  object 
 16  Accessible en ligne                       448047 non-null  object 
 17  Publication dans theses.fr                448047 non-null  object 
 18  Mise a jour dans theses.fr                447870 non-null  object 
 19  Discipline_prédi                         448047 non-null  object 
 20  Genre                                     448047 non-null  object 
 21  etablissement_rec                         444973 non-null  object 
 22  Langue_rec                                383927 non-null  object 
dtypes: float64(1), int64(1), object(21)
memory usage: 78.6+ MB
In [7]:
these = these.set_index('Unnamed: 0')#transformons cette variable en index
  • Comme nous avons dans l'exercice une période de réference à utiliser, nous allons creer le dataframe intermediaire à utiliser dans l'exercice.
In [8]:
these84_18 = these[(these.Year > 1984) & (these.Year<2019)]
  • Nous sommes interpellé sur deux variables la varibale année et la variable Discipline_prédi , nous allons donc travailler sur ces deux variables .
In [9]:
these84_18.rename(columns={'Discipline_prédi': 'Discipline_agreges'}, inplace=True)
these84_18['Discipline_agreges'] = these84_18['Discipline_agreges'].str.replace('é', 'e', regex=False)
In [10]:
these84_18.info()
<class 'pandas.core.frame.DataFrame'>
Index: 379157 entries, 2 to 448031
Data columns (total 22 columns):
 #   Column                                    Non-Null Count   Dtype  
---  ------                                    --------------   -----  
 0   Auteur                                    379157 non-null  object 
 1   Identifiant auteur                        309328 non-null  object 
 2   Titre                                     379156 non-null  object 
 3   Directeur de these                        379145 non-null  object 
 4   Directeur de these (nom prenom)           379145 non-null  object 
 5   Identifiant directeur                     379157 non-null  object 
 6   Etablissement de soutenance               379156 non-null  object 
 7   Identifiant etablissement                 362083 non-null  object 
 8   Discipline                                379157 non-null  object 
 9   Statut                                    379157 non-null  object 
 10  Date de premiere inscription en doctorat  5300 non-null    object 
 11  Date de soutenance                        379157 non-null  object 
 12  Year                                      379157 non-null  float64
 13  Langue de la these                        379157 non-null  object 
 14  Identifiant de la these                   379157 non-null  object 
 15  Accessible en ligne                       379157 non-null  object 
 16  Publication dans theses.fr                379157 non-null  object 
 17  Mise a jour dans theses.fr                378980 non-null  object 
 18  Discipline_agreges                        379157 non-null  object 
 19  Genre                                     379157 non-null  object 
 20  etablissement_rec                         376463 non-null  object 
 21  Langue_rec                                373551 non-null  object 
dtypes: float64(1), object(21)
memory usage: 66.5+ MB
In [11]:
# extrayons les données dont nous avons besoin :
these_exo= these84_18[[ 'Date de soutenance', 'Discipline_agreges']]
In [12]:
these_exo= these_exo.reset_index(drop=True)
In [13]:
these_exo["Date"] =  pd.to_datetime(these_exo['Date de soutenance'])#changeons le format de la colonne date de soutenance dans une nouvelle colonne date
In [14]:
these_exo["Date"].head()#verification
Out[14]:
0   1993-01-01
1   2008-11-24
2   2005-01-07
3   2009-08-12
4   2013-10-01
Name: Date, dtype: datetime64[ns]
In [15]:
these_exo['Année']= these_exo["Date"].dt.year
In [16]:
these_exo.head()
Out[16]:
Date de soutenance Discipline_agreges Date Année
0 01-01-93 Medecine 1993-01-01 1993
1 24-11-08 Droit et Science Politique 2008-11-24 2008
2 01-07-05 Droit et Science Politique 2005-01-07 2005
3 08-12-09 Droit et Science Politique 2009-08-12 2009
4 10-01-13 Biologie 2013-10-01 2013
In [17]:
these_exo= these_exo[[ 'Date', 'Année', 'Discipline_agreges']]# faisons les extractions nécessaires
these_exo.head()
Out[17]:
Date Année Discipline_agreges
0 1993-01-01 1993 Medecine
1 2008-11-24 2008 Droit et Science Politique
2 2005-01-07 2005 Droit et Science Politique
3 2009-08-12 2009 Droit et Science Politique
4 2013-10-01 2013 Biologie
In [18]:
these_exo['Discipline_agreges'].unique()
Out[18]:
array(['Medecine', 'Droit et Science Politique', 'Biologie', 'SHS',
       'Langues et Litteratures', 'Psychologie', 'Economie Gestion',
       'Informatique', 'Materiaux, Milieux et Chimie', 'Poubelle',
       "Sciences de l'education", "Science de l'ingenieur",
       'Mathematiques', 'Science de la Terre',
       'Mathematiques et Informatique'], dtype=object)
  • Travaillons sur la discipline Poubelle :
In [19]:
g = these84_18[these84_18['Discipline_agreges']== 'Poubelle' ]
g['Discipline'].unique()# toutes les matieres correspondent aux STAPS
Out[19]:
array(['Staps', 'Sciences du sport (staps)', 'Doctorat staps (ed 536)',
       'Staps : les fondements neurobiologiques, physiologiques et psychosociologiques des habiletes sportives',
       'Science', 'Interdisciplinaire', 'Doctorat STAPS',
       'STAPS. Sciences sociales', 'Staps - shs',
       'STAPS mention Sociologie',
       'Sociologie. Sciences et techniques des activites physiques et sportives (STAPS)',
       'Sciences et techniques des activites physiques et sportives (STAPS)',
       'STAPS, Readaptation, Sport - Sante', 'Sport',
       'STAPS - Option sociologie', 'Doctorat en psychologie et en STAPS',
       'Biologie - Sante. STAPS, Readaptation, Sport - Sante',
       'Didactique des disciplines.Activites physiques et sportives',
       'Developpement',
       'Science technique des activites physique et sportive (STAPS)',
       'Epistemologie', 'Biologie, Sante et Sciences. STAPS',
       'Performance motrice, adaptation, sport',
       'Sciences et Techniques des Activites Physiques et Sportives (STAPS)',
       'Biologie et Sante. STAPS', 'Management du sport',
       'Biologie-Sante. STAPS readaptation, Sport-Sante', 'STAPS',
       'Biologie Sante. STAPS Readaptation, Sport-Sante',
       'Science appliquee',
       'Sciences et Techniques des Activites Physiques et Sportives. Performance motrice, adaptations, sport',
       'Sciences et techniques des activite physiques et sportives',
       'Construction des savoirs scientifiques, Didactique, Histoire et EpistemologieConstruction des savoirs scientifiques, Didactique, Histoire et Epistemologie',
       'STAPS, sociologie',
       'Sciences et techniques en activites physiques et sportives. Sciences et sante "Performance motrice, adaptation et sport"',
       'STAPS. Performance motrice, adaptation et sports',
       'Sciences. Didactique de la biologie. Museologie des sciences',
       'Didactique des activites physiques et sportives',
       'Performance motrice, adaptations, sport', 'Sciences. Staps',
       'Activite physiques et sportives',
       'Performance motrice, adaptation et sport',
       'Sciences. Management du sport'], dtype=object)
In [20]:
#Changeons le nom des variables et des items à corriger pour une meilleure compréhension :
these_exo['Discipline_agreges'] = these_exo['Discipline_agreges'].replace('Poubelle', 'Sciences et Techniques des Activités Physiques et Sportives')#STAPS
these_exo['Discipline_agreges'] = these_exo['Discipline_agreges'].replace('SHS', 'Sciences Humaines et Sociales')

these_exo.rename(columns={'Discipline_agreges': 'Discipline'}, inplace=True)

these_exo.head()
Out[20]:
Date Année Discipline
0 1993-01-01 1993 Medecine
1 2008-11-24 2008 Droit et Science Politique
2 2005-01-07 2005 Droit et Science Politique
3 2009-08-12 2009 Droit et Science Politique
4 2013-10-01 2013 Biologie
In [21]:
print(these_exo.head())
        Date  Année                  Discipline
0 1993-01-01   1993                    Medecine
1 2008-11-24   2008  Droit et Science Politique
2 2005-01-07   2005  Droit et Science Politique
3 2009-08-12   2009  Droit et Science Politique
4 2013-10-01   2013                    Biologie
In [22]:
sout_disc_annee = these_exo.groupby(['Année', 'Discipline']).size().reset_index(name='Nombre de Soutenances')
sout_disc_annee.head() #extraction du nombre de soutenances par discipline et par année       
Out[22]:
Année Discipline Nombre de Soutenances
0 1985 Biologie 695
1 1985 Droit et Science Politique 168
2 1985 Economie Gestion 220
3 1985 Informatique 45
4 1985 Langues et Litteratures 268
In [23]:
sout_disc_annee1 = sout_disc_annee.pivot(index='Année', columns='Discipline', values='Nombre de Soutenances')
sout_disc_annee1.head() # Pour pouvoir faire des graphiques à aires il nous faut faire un tableau croisé afin d'avoir un dataframe à utiliser pour le reste de l'exercie 
Out[23]:
Discipline Biologie Droit et Science Politique Economie Gestion Informatique Langues et Litteratures Materiaux, Milieux et Chimie Mathematiques Mathematiques et Informatique Medecine Psychologie Science de l'ingenieur Science de la Terre Sciences Humaines et Sociales Sciences de l'education Sciences et Techniques des Activités Physiques et Sportives
Année
1985 695.0 168.0 220.0 45.0 268.0 331.0 120.0 2.0 434.0 94.0 136.0 109.0 380.0 5.0 NaN
1986 967.0 400.0 390.0 69.0 415.0 635.0 331.0 1.0 364.0 239.0 244.0 243.0 863.0 1.0 NaN
1987 1716.0 413.0 413.0 101.0 646.0 1359.0 766.0 8.0 225.0 726.0 367.0 626.0 1069.0 3.0 1.0
1988 1815.0 374.0 332.0 121.0 457.0 1233.0 610.0 12.0 3736.0 688.0 340.0 453.0 868.0 6.0 NaN
1989 1649.0 378.0 281.0 144.0 415.0 1405.0 723.0 10.0 3926.0 647.0 399.0 415.0 701.0 6.0 3.0

Creons une palette de couleurs ajustée pour refléter les relations entre les matières, en tenant compte des matières similaires ou proches, tout en attribuant des couleurs distinctes aux groupes similaires :

  • Sciences naturelles et exactes : Biologie, Matériaux, Milieux et Chimie, Médecine, Mathématiques, Mathématiques et Informatique, Science de la Terre, Science de l'ingénieur.
  • Sciences humaines et sociales : Droit et Science Politique, Sciences Humaines et Sociales, Langues et Littératures, Psychologie, Sciences de l'éducation.
  • Sciences économiques et de gestion : Economie Gestion.
  • Technologies et informatique : Informatique, Mathematiques et Informatique.
  • Sports et activités physiques : Sciences et Techniques des Activités Physiques et Sportives.
In [24]:
# Nous avons créer ce dictionnaire des matières et couleurs associées car les couleurs sont nombreuses et nous n'avons pas de palettes prédéfinies qui ont assez de couleur sans tenir compte du fait que nous voulions des couleurs qui associent les branches d'étude 
matieres = {
    'Biologie': '#2ca02c',  
    'Droit et Science Politique': '#d62728',  
    'Economie Gestion': '#ff7f0e',  
    'Informatique': '#1f77b4',  
    'Langues et Litteratures': '#9467bd',  
    'Materiaux, Milieux et Chimie': '#8c564b',  
    'Mathematiques': '#e377c2',  
    'Mathematiques et Informatique': '#7f7f7f',  
    'Medecine': '#bcbd22',  
    'Psychologie': '#17becf',  
    "Science de l'ingenieur": '#ff9896',  
    'Science de la Terre': '#c5b0d5',  
    'Sciences Humaines et Sociales': '#f7b7a3',  
    "Sciences de l'education": '#aec7e8',  
    'Sciences et Techniques des Activités Physiques et Sportives': '#98df8a'  
}

# Affichage de la palette
plt.figure(figsize=(8, 6))
for i, (matiere, couleur) in enumerate(matieres.items()):
    plt.plot([0, 1], [i, i], color=couleur, lw=6)
plt.yticks(range(len(matieres)), list(matieres.keys()))
plt.title("Palette de couleurs pour les matières (groupées par affinités)")
plt.show()
No description has been provided for this image
In [25]:
# Dictionnaire des matières et couleurs associées 
matieres = {
    'Biologie': '#2ca02c',  
    'Droit et Science Politique': '#d62728',  
    'Economie Gestion': '#ff7f0e',  
    'Informatique': '#1f77b4',  
    'Langues et Litteratures': '#9467bd',  
    'Materiaux, Milieux et Chimie': '#8c564b',  
    'Mathematiques': '#e377c2',  
    'Mathematiques et Informatique': '#7f7f7f',  
    'Medecine': '#bcbd22',  
    'Psychologie': '#17becf',  
    "Science de l'ingenieur": '#ff9896',  
    'Science de la Terre': '#c5b0d5',  
    'Sciences Humaines et Sociales': '#f7b7a3',  
    "Sciences de l'education": '#aec7e8',  
    'Sciences et Techniques des Activités Physiques et Sportives': '#98df8a'  
}

# Vérification 
for matière, couleur in matieres.items():
    try:
        mcolors.to_rgba(couleur)  
    except ValueError:
        print(f"Couleur invalide pour {matière}: {couleur}")

#listes des couleurs
colors = list(matieres.values())

# stackplot
plt.figure(figsize=(15, 6))
plt.stackplot(sout_disc_annee1.index, sout_disc_annee1.T, labels=sout_disc_annee1.columns, alpha=0.8, colors=colors)
plt.xlim(1985, 2018)
plt.grid(True)
plt.legend(loc='upper left', bbox_to_anchor=(1, 1),title="Disciplines")

# customiser le graphique
plt.title("Évolution quantitative du nombre de thèses soutenues par discipline (1985-2018)", fontsize=16, fontweight='bold')
plt.xlabel("Année")
plt.ylabel("Nombre de thèses soutenues")
plt.tight_layout()

plt.show()
No description has been provided for this image
In [26]:
# Dictionnaire des matières et couleurs associées 
matieres = {
    'Biologie': '#2ca02c',  
    'Droit et Science Politique': '#d62728',  
    'Economie Gestion': '#ff7f0e',  
    'Informatique': '#1f77b4',  
    'Langues et Litteratures': '#9467bd',  
    'Materiaux, Milieux et Chimie': '#8c564b',  
    'Mathematiques': '#e377c2',  
    'Mathematiques et Informatique': '#7f7f7f',  
    'Medecine': '#bcbd22',  
    'Psychologie': '#17becf',  
    "Science de l'ingenieur": '#ff9896',  
    'Science de la Terre': '#c5b0d5',  
    'Sciences Humaines et Sociales': '#f7b7a3',  
    "Sciences de l'education": '#aec7e8',  
    'Sciences et Techniques des Activités Physiques et Sportives': '#98df8a'  
}

for matière, couleur in matieres.items():
    try:
        mcolors.to_rgba(couleur)  # Vérifie que la couleur est valide
    except ValueError:
        print(f"Couleur invalide pour {matière}: {couleur}")

# Extraire les couleurs sous forme de liste
colors = list(matieres.values())

# Normaliser les données à 100%
sout_disc_annee1_normalized = sout_disc_annee1.div(sout_disc_annee1.sum(axis=1), axis=0)

plt.figure(figsize=(15, 6))

# stackplot
plt.stackplot(sout_disc_annee1_normalized.index, sout_disc_annee1_normalized.T, 
              labels=sout_disc_annee1.columns, alpha=0.8, colors=colors)  # Passer la liste de couleurs

# Limiter l'axe des x entre 1985 et 2018
plt.xlim(1985, 2018)
plt.ylim(0, 1)

# legende
plt.legend(loc='upper left', bbox_to_anchor=(1, 1), title="Discipline")

# Ajouter le titre et les labels des axes
plt.title("Évolution du pourcentage de theses soutenues par discipline et par année (1985-2018)", fontsize=16, fontweight='bold')
plt.xlabel("Année")
plt.ylabel("Proportion de thèses soutenues (%)")
plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, _: f'{x*100:.0f}%'))# formatge axe des y:
plt.grid(True)
plt.tight_layout()
plt.show()
No description has been provided for this image
In [27]:
#Exemple ploty
fig = px.area(sout_disc_annee, x="Année", y="Nombre de Soutenances", color="Discipline", title ='Évolution des soutenances de théses par  discipline ')
fig.show()
In [28]:
# Définir la palette de couleurs
matieres = {
    'Biologie': '#2ca02c',  
    'Droit et Science Politique': '#d62728',  
    'Economie Gestion': '#ff7f0e',  
    'Informatique': '#1f77b4',  
    'Langues et Litteratures': '#9467bd',  
    'Materiaux, Milieux et Chimie': '#8c564b',  
    'Mathematiques': '#e377c2',  
    'Mathematiques et Informatique': '#7f7f7f',  
    'Medecine': '#bcbd22',  
    'Psychologie': '#17becf',  
    "Science de l'ingenieur": '#ff9896',  
    'Science de la Terre': '#c5b0d5',  
    'Sciences Humaines et Sociales': '#f7b7a3',  
    "Sciences de l'education": '#aec7e8',  
    'Sciences et Techniques des Activités Physiques et Sportives': '#98df8a'  
}

# Extraire les couleurs dans l'ordre des colonnes de sout_disc_annee1
colors = [matieres[col] for col in sout_disc_annee1.columns]
sns.set_theme(style='whitegrid')
fig, ax = plt.subplots(figsize=(15, 6))

# Définir l'axe x et la largeur des barres
x = sout_disc_annee1.index
bar_width = 0.8
bottom_values = np.zeros(len(x))

# Dessiner les barres empilées avec les couleurs de matières
for col, color in zip(sout_disc_annee1.columns, colors):
    ax.bar(x, sout_disc_annee1[col], bottom=bottom_values, label=col, width=bar_width, color=color)
    bottom_values += sout_disc_annee1[col]

# Limiter l'axe des X
plt.xlim(1984, 2019)

# customiser le graphique
ax.set_title("Évolution du nombre de theses soutenues par discipline (1985-2018)", fontsize=16, fontweight='bold')
ax.set_xlabel("Année")
ax.set_ylabel("Nombre de soutenances")
ax.legend(loc='upper left', bbox_to_anchor=(1, 1),title="Discipline")
plt.tight_layout()
plt.show()
No description has been provided for this image
In [29]:
# Dictionnaire des matières et couleurs associées (couleurs en format hexadécimal)
matieres = {
    'Biologie': '#2ca02c',  
    'Droit et Science Politique': '#d62728',  
    'Economie Gestion': '#ff7f0e',  
    'Informatique': '#1f77b4',  
    'Langues et Litteratures': '#9467bd',  
    'Materiaux, Milieux et Chimie': '#8c564b',  
    'Mathematiques': '#e377c2',  
    'Mathematiques et Informatique': '#7f7f7f',  
    'Medecine': '#bcbd22',  
    'Psychologie': '#17becf',  
    "Science de l'ingenieur": '#ff9896',  
    'Science de la Terre': '#c5b0d5',  
    'Sciences Humaines et Sociales': '#f7b7a3',  
    "Sciences de l'education": '#aec7e8',  
    'Sciences et Techniques des Activités Physiques et Sportives': '#98df8a'  
}

# Normaliser les données pour obtenir des pourcentages par ligne
sout_disc_annee1_percentage = sout_disc_annee1.div(sout_disc_annee1.sum(axis=1), axis=0) * 100

# Extraire les couleurs dans l'ordre des colonnes de sout_disc_annee1_percentage
colors = [matieres[col] for col in sout_disc_annee1_percentage.columns]

# Paramètres pour le graphique
sns.set_theme(style='white')
fig, ax = plt.subplots(figsize=(15, 6))

x = sout_disc_annee1_percentage.index
bar_width = 0.8
bottom_values = np.zeros(len(x))

# Création du graphique en pourcentage avec les couleurs des matières
for col, color in zip(sout_disc_annee1_percentage.columns, colors):
    ax.bar(x, sout_disc_annee1_percentage[col], bottom=bottom_values, label=col, width=bar_width, color=color)
    bottom_values += sout_disc_annee1_percentage[col]

# Personnalisation de l'axe X et Y
plt.xlim(1984, 2019)
ax.set_title("Évolution annuelle du nombre de théses soutenues par discipline en pourcentage (1985-2018)", fontsize=16, fontweight='bold')
ax.set_xlabel("Année")
ax.set_ylabel("Proportion de thèses soutenues (%)")
ax.legend(loc='upper left', bbox_to_anchor=(1, 1),title="Discipline")
plt.gca().yaxis.set_major_formatter(FuncFormatter(lambda x, _: f'{x:.0f}%'))

# Affichage du graphique
plt.tight_layout()
plt.show()
No description has been provided for this image

Exercice 2 :¶

In [30]:
sns.set_style("darkgrid")
plt.figure(figsize=(8, 6))
plt.grid(visible=True, color='gray', linestyle='--', linewidth=0.5)

#  lignes horizontales
for val in np.linspace(0, 20, 17): 
    plt.axhline(y=val, color='black', linestyle='-.', linewidth=0.2, zorder=1) #distance entre les lignes et priorité de visibilité de la lignes
# lignes verticales
for val in np.linspace(4, 8, 9): 
    plt.axvline(x=val, color='black', linestyle='-.', linewidth=0.2, zorder=1)#distance entre les lignes et priorité de visibilité de la lignes
plt.title('Grid personnalisé', fontsize=14)
plt.xlabel("X", fontsize=12)
plt.ylabel("Y", fontsize=12)
plt.show()
No description has been provided for this image
In [31]:
sns.set_style("whitegrid")

#Charger le jeu de données
iris = sns.load_dataset('iris')

#figure 
plt.figure(figsize=(8, 6))
colors = {'setosa': 'purple', 'versicolor': 'green', 'virginica': 'yellow'}

# Nous allons mainternant tracer les histogrammes :
for specie in iris['species'].unique():
    sns.histplot(iris[iris['species'] == specie]['sepal_length'], kde=False, color=colors[specie], alpha=0.6,
                 label=specie, binwidth=0.2, linewidth=2, edgecolor=colors[specie], stat='count')

# lignes horizontales et verticales
for val in np.arange(0, 21, 1.25): 
    plt.axhline(y=val, color='gray', linestyle='-.', linewidth=0.2)
for val in np.arange(4, 8.1, 0.5): 
    plt.axvline(x=val, color='gray', linestyle='-.', linewidth=0.2)

# Paramètres des axes
plt.xlabel('Longueur du Sépale')
plt.ylabel('Count')
plt.xlim(4, 8)  # Limiter l'axe X entre 4 et 8
plt.xticks(np.arange(5, 9, 1), [5, 6, 7, 8])  # Ajuster les ticks

# Personnaliser la grille
plt.grid(True, which='both', axis='both', color='gray', linestyle='--', linewidth=0.3, alpha=0.3)

# Personnalisér la legendes carrés
# Augmenter la taille des carrés en ajustant markersize
handles = [Line2D([0], [0], marker='s', color='w', markerfacecolor=color, markersize=15,markeredgecolor=color,  
        markeredgewidth=6, label=specie)
           for specie, color in colors.items()]  

# Créer un handle pour le titre "Espèce :"
title_handle = Line2D([0], [0], color='w', label='Espèces :')

# Ajouter la légende avec le titre et les carrés colorés
plt.legend(handles=[title_handle] + handles, loc='upper center', bbox_to_anchor=(0.5, 1.08), ncol=4, 
           frameon=False, handletextpad=0.3, columnspacing=0.3)  # Ajuster handletextpad distance entre titre et legende et columnspacing distance entre les handles de la légende

# Titre en bas et en gras
plt.title('Répartition du nombre de fleurs par longueur de sépale et par espèce(IRIS)', fontsize=13, fontweight='bold', loc='center', y=-0.2)
plt.show()
No description has been provided for this image

Exercice 3 :¶

In [32]:
# Données
x = ['A', 'B', 'C', 'D', 'E']
y = [0.29, 0.78, 0.9, 0.2, 0.6]

# Définir la palette personnalisée entre #0b1925 et #a5c6e2
colors = [(11/255, 25/255, 37/255), (165/255, 198/255, 226/255)]  
cmap = LinearSegmentedColormap.from_list("custom_blues", colors)

# Création du barplot
plt.figure(figsize=(6, 6))

ax = plt.gca()
ax.set_facecolor('#f0f0f0')  #  un fond gris très clair

# Ajouter des lignes horizontales pour les intervalles de 0.25
for val in np.arange(0, 1.05, 0.25):
    plt.axhline(y=val, color='white', linestyle='-', linewidth=1.5, zorder=1)

# Ajouter des lignes horizontales plus fines pour les intervalles de 0.125
for val in np.arange(0, 1.05, 0.125):
    if val % 0.25 != 0:  # Exclure les lignes déjà tracées pour 0.25
        plt.axhline(y=val, color='white', linestyle='--', linewidth=1, zorder=1)

# Normalisation des valeurs de 'y' entre 0.2 et 0.9
min_val = 0.2
max_val = 0.9
norm = plt.Normalize(min_val, max_val)

colors = cmap(norm(y))  # Appliquer le dégradé

bars = plt.bar(x, y, color=colors, zorder=2)  # Appliquer les couleurs de la palette et zorder plus élevé pour les barres

# Ajouter une barre de couleurs
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)  
sm.set_array([])  

# Création de la colorbar avec un aspect ajusté
cbar = plt.colorbar(sm, ax=ax, fraction=0.05, pad=0.14, aspect=15)  

# Enlever l'encadrement de la colorbar
cbar.outline.set_visible(False)

cbar.ax.set_title('y', fontsize=14, fontweight='bold', pad=10)  # Positionner le titre colbar

# Rendre les ticks de la colorbar en gras
cbar.ax.yaxis.set_tick_params(labelsize=12)  
for label in cbar.ax.get_yticklabels():
    label.set_fontweight('bold') 

cbar.set_ticks(np.arange(min_val, max_val + 0.1, 0.2))  # Ticks de 0.2 à 0.9

# Ajouter des tirets blancs aux ticks 0.2, 0.4, 0.6 et 0.8
for tick in np.arange(0.2, 1.0, 0.2):
    cbar.ax.axhline(y=tick, color='white', linestyle='--', linewidth=2)

plt.xlabel('X', fontsize=14, fontweight='bold', labelpad=15)
plt.ylabel('y', fontsize=14, fontweight='bold')

# Ajuster les ticks de l'axe Y
ax.set_yticks(np.arange(0, 1.05, 0.25))  


plt.ylim(-0.05, 0.95)

# Ajouter la grille verticale en blanc, mais en arrière des barres
plt.grid(True, axis='x', color='white', linestyle='-', linewidth=1.5, zorder=0)  

# Ajouter des flèches rouges sous le graphique, mais en dehors de l'aire du graphique avec la tête de la flèche vers le bas
for tick in ax.get_xticks():
    # Position des flèches (elles sont en dehors du graphique)
    ax.annotate('', xy=(tick, -0.05), xytext=(tick, -0.12),  # Position des flèches
                arrowprops=dict(facecolor='red', edgecolor='red', arrowstyle='<-', lw=1, shrinkA=0, shrinkB=5, zorder=3))

# Déplacer les labels juste sous les flèches
ax.set_xticklabels(x, fontsize=12, fontweight='bold', rotation=0, ha='center', position=(0, -0.05))

# Enlever la bordure noire
for spine in ax.spines.values():
    spine.set_visible(False)
plt.show()
No description has been provided for this image
  • J'ai pris la liberté de telecharger un fichier dans le site de l'Agence Nationale de la Statistique et de la Démographique du Sénégal car je n'ai pas trouver de données pour la figure 3 du devoir. Je vais maintenant l'utiliser pour le travail demandé.
In [33]:
recensement = pd.read_csv("data-recensement.csv")
In [34]:
recensement.head()
Out[34]:
Region Departement COM_ARRT_VILLE COMMUNE QUARTIER_VILLAGE_HAMEAU CONCESSION MENAGE HOMMES FEMMES POPULATION
0 ZIGUINCHOR BIGNONA BIGNONA BIGNONA BASSENE 575 829 3169 3034 6203
1 ZIGUINCHOR BIGNONA BIGNONA BIGNONA CHATEAU D'EAU 389 658 2266 2166 4432
2 ZIGUINCHOR BIGNONA BIGNONA BIGNONA KADIAMOR 569 663 2315 2260 4575
3 ZIGUINCHOR BIGNONA BIGNONA BIGNONA MANGUILINE 334 453 1529 1618 3147
4 ZIGUINCHOR BIGNONA BIGNONA BIGNONA MEDINA PLATEAU 980 1493 5301 4984 10285
In [35]:
recensement.shape
Out[35]:
(520, 10)
In [36]:
recensement['COMMUNE'].unique()
Out[36]:
array(['BIGNONA', 'THIONCK ESSYL', 'DJIBIDIONE', 'OULAMPANE', 'SINDIAN',
       'SUELLE', 'BALINGHORE', 'DIEGOUNE', 'KARTIACK', 'MANGAGOULACK',
       'MLOMP', 'COUBALAN', 'NIAMONE', 'OUONCK', 'TENGHORI', 'DJINAKY',
       'KAFOUNTINE', 'KATABA 1', 'DIOULOULOU'], dtype=object)
In [37]:
recensement['QUARTIER_VILLAGE_HAMEAU'].nunique()
Out[37]:
513
In [57]:
sns.set_style("white")

plt.figure(figsize=(10, 6))

# Extraire les valeurs uniques de COM_ARRT_VILLE pour générer des couleurs
com_arrt_ville_unique = recensement['COM_ARRT_VILLE'].unique()

# Créer une palette de couleurs
colors = plt.cm.get_cmap('tab20', len(com_arrt_ville_unique)) 

# Créer un dictionnaire pour associer chaque COM_ARRT_VILLE à une couleur
color_dict = {com: colors(i) for i, com in enumerate(com_arrt_ville_unique)}

bars = plt.bar(recensement['COMMUNE'], recensement['POPULATION'], 
               color=[color_dict[com] for com in recensement['COM_ARRT_VILLE']])
plt.xlabel('Commune')
plt.ylabel('Population Totale')
plt.title('Population du département Bignona par Commune (Recensement General 2024)')

# Ajuster les xticks pour qu'ils soient bien alignés avec les barres
plt.xticks(rotation=45, ha='right')

# Ajouter une légende pour les couleurs 
handles = [plt.Rectangle((0, 0), 1, 1, color=color_dict[com]) for com in com_arrt_ville_unique]
plt.legend(handles, com_arrt_ville_unique, title='Arrondissement', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
plt.close()
No description has been provided for this image
In [39]:
plt.figure(figsize=(10, 6))
com_arrt_ville_unique = recensement['COM_ARRT_VILLE'].unique()
colors = plt.cm.get_cmap('tab20', len(com_arrt_ville_unique))  # Choisir une palette appropriée
color_dict = {com: colors(i) for i, com in enumerate(com_arrt_ville_unique)}
bars = plt.bar(recensement['COMMUNE'], recensement['POPULATION'], 
               color=[color_dict[com] for com in recensement['COM_ARRT_VILLE']])
plt.xlabel('Commune')
plt.ylabel('Population Totale')
plt.title('Population du département Bignona par Commune (Recensement General 2024)')

plt.xticks(rotation=90, ha='right')

# Ajouter une légende pour les couleurs (basée sur COM_ARRT_VILLE)
handles = [plt.Rectangle((0, 0), 1, 1, color=color_dict[com]) for com in com_arrt_ville_unique]
plt.legend(handles, com_arrt_ville_unique, title='Arrondissement', bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()
No description has been provided for this image

Exercice 4 :¶

In [40]:
sns.set_style("white")

fig = plt.figure(figsize=(8, 6))
gs = gridspec.GridSpec(1, 2, width_ratios=[2, 1])  # Le premier graphique est 2 fois plus large

# Créer les listes X et Y
X = list(range(1, 11))
Y = list(range(1, 11))

# Premier graphique
ax0 = fig.add_subplot(gs[0])
ax0.scatter(X, Y, marker='o', facecolors='none', edgecolors='k', s=20)
ax0.set_aspect('equal', adjustable='box')#graphique carré
# Ajouter la légende au premier graphique
ax0.legend(['Small Margins\npar(mar = c(2,2,2,2))'], 
           loc='center',  
           fontsize=12, 
           bbox_to_anchor=(0.5, 1.03),  # Placer la légende au-dessus du graphique
           frameon=False,
           handlelength=0,  # Supprimer les handles
           markerscale=0,  # Enlever le marqueur
           labelspacing=1.5)

# Deuxième graphique, centré dans la deuxième colonne
# Nous centrons le graphique dans la partie droite de la figure
ax1 = fig.add_axes([0.75, 0.375, 0.25, 0.25])  # Le 0.75 est la position x pour centrer
ax1.scatter(X, Y, marker='o', facecolors='none', edgecolors='k', s=10)
ax1.set_xlabel('Index')  # étiquette pour l'axe des X
ax1.set_ylabel('1:10')   # étiquette pour l'axe des Y

# Ajuster les limites pour forcer un graphique carré
ax1.set_aspect('equal', adjustable='box')

# Ajouter une légende au second graphique
ax1.legend(['Small Margins\npar(mar = c(2,2,2,2))'], 
           loc='center',  
           fontsize=8, 
           bbox_to_anchor=(0.5, 1.065),  # Placer la légende au-dessus du graphique
           frameon=False,
           handlelength=0,  # Supprimer les handles
           markerscale=0,  # Enlever le marqueur
           labelspacing=1.5)

plt.tight_layout() 
plt.show()
No description has been provided for this image
In [41]:
fig = plt.figure(figsize=(12, 8))
# Gridspec pour une disposition 1x2 avec des ratios de largeur
gs = gridspec.GridSpec(1, 2, width_ratios=[2, 1])  # Le premier graphique est 2 fois plus large
X = list(range(1, 11))
Y = list(range(1, 11))

# Premier sous-graphe 
ax0 = fig.add_subplot(gs[0])
ax0.scatter(X, Y, marker='o', facecolors='none', edgecolors='k', s=40)
ax0.set_aspect('equal', adjustable='box')

# Ajouter la légende au premier graphique
ax0.legend(['Small Margins\npar(mar = c(2,2,2,2))'], 
           loc='center',  
           fontsize=16, 
           bbox_to_anchor=(0.5, 1.02),  # Placer la légende au-dessus du graphique
           frameon=False,
           handlelength=0,  # Supprimer les handles
           markerscale=0,  # Enlever le marqueur
           labelspacing=1.5,
           prop={'family': 'Times New Roman', 'weight': 'bold'})

# Deuxième sous-graphe (4x4), centré dans la deuxième colonne
# Nous centrons le graphique dans la partie droite de la figure
ax1 = fig.add_axes([0.75, 0.375, 0.25, 0.25])  # Le 0.75 est la position x pour centrer
ax1.scatter(X, Y, marker='o', facecolors='none', edgecolors='r', s=10)
ax1.set_xlabel('Index')  # Ajouter l'étiquette pour l'axe des X
ax1.set_ylabel('1:10')   # Ajouter l'étiquette pour l'axe des Y
ax1.set_aspect('equal', adjustable='box')

# Ajouter une légende au second graphique
ax1.legend(['Small Margins\npar(mar = c(2,2,2,2))'], 
           loc='center',  
           fontsize=8, 
           bbox_to_anchor=(0.5, 1.06),  # Placer la légende au-dessus du graphique
           frameon=False,
           handlelength=0,  # Supprimer les handles
           markerscale=0,  # Enlever le marqueur
           labelspacing=1.5,
           prop={'family': 'Garamond', 'weight': 'bold'})  # Retirer l'espace supplémentaire

# Définir les ticks de l'axe X du deuxième graphique à [2, 4, 6, 8]
ax1.set_xticks([2, 4, 6, 8, 10])

fig.text(0.5, -0.1, "Graphique personnalisé ", 
         ha='center', fontsize=16, fontweight='bold', fontfamily='Times New Roman')
plt.tight_layout()  
plt.show()
No description has been provided for this image
In [42]:
sns.set_style("white")

#chiffres romains :
def to_roman(x, pos=None):
    roman_numerals = [
        (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')
    ]
    result = ''
    for value, numeral in roman_numerals:
        while x >= value:
            result += numeral
            x -= value
    return result

# Créer une figure
fig = plt.figure(figsize=(12, 8))

# Gridspec pour une disposition 1x2 avec des ratios de largeur
gs = gridspec.GridSpec(1, 2, width_ratios=[2, 1])  # Le premier graphique est 2 fois plus large

X = list(range(1, 11))
Y = list(range(1, 11))

# Premier graphique
ax0 = fig.add_subplot(gs[0])
ax0.scatter(X, Y, marker='o', facecolors='none', edgecolors='k', s=40)

ax0.set_aspect('equal', adjustable='box')#ajuster graphique

# Changer le format d'écriture des labels du premier graphique
ax0.set_xlabel(' X', fontsize=14, family='Comic Sans MS', style='italic', weight='normal', color='purple')
ax0.set_ylabel(' Y', fontsize=14, family='Comic Sans MS', style='italic', weight='normal', color='purple')

# Ajouter la légende au premier graphique
ax0.legend(['Small Margins\npar(mar = c(2,2,2,2))'], 
           loc='center',  
           fontsize=16, 
           bbox_to_anchor=(0.5, 1.02),  # Placer la légende au-dessus du graphique
           frameon=False,
           handlelength=0,  # Supprimer les handles
           markerscale=0,  # Enlever le marqueur
           labelspacing=1.5,
           prop={'family': 'Times New Roman', 'weight': 'bold'})

# Deuxième graphique , centré dans la deuxième colonne
ax1 = fig.add_axes([0.75, 0.375, 0.25, 0.25])  # Le 0.75 est la position x pour centrer
ax1.scatter(X, Y, marker='o', facecolors='none', edgecolors='r', s=10)
ax1.set_xlabel('Index')  # Legende pour l'axe des X
ax1.set_ylabel('1:10')   # Legende pour l'axe des Y

ax1.set_aspect('equal', adjustable='box')

#  légende au second graphique
ax1.legend(['Small Margins\npar(mar = c(2,2,2,2))'], 
           loc='center',  
           fontsize=8, 
           bbox_to_anchor=(0.5, 1.06),  # Placer la légende au-dessus du graphique
           frameon=False,
           handlelength=0,  # Supprimer les handles
           markerscale=0,  # Enlever le marqueur
           labelspacing=1.5,
           prop={'family': 'Garamond', 'weight': 'bold'})  # Retirer l'espace supplémentaire

# Définir les ticks de l'axe X du deuxième graphique à [2, 4, 6, 8]
ax1.set_xticks([2, 4, 6, 8, 10])

# formatage pour les axes X et Y
ax1.xaxis.set_major_formatter(FuncFormatter(to_roman)) 
ax1.yaxis.set_major_formatter(FuncFormatter(to_roman)) 


#Titre du graphique subplots
fig.text(0.5, -0.1, "Graphique personnalisé", 
         ha='center', fontsize=16, fontweight='bold', fontfamily='Times New Roman')
plt.tight_layout() 
plt.show()
No description has been provided for this image

Exercice 5:¶

In [43]:
#echelle logarithmique sur l axe des X
x = np.linspace(1, 10, 100)
y = x ** 2  # relation quadriatique

plt.plot(x, y, label="y = x^2")

# échelle logarithmique sur l'axe Y
plt.yscale('log')

plt.title("Exemple de visualisation avec échelle logarithmique sur l'axe Y")
plt.xlabel("X")
plt.ylabel("Y")
plt.show()
No description has been provided for this image
In [44]:
sns.set_style("dark")

#Autre exemple
date = ["28 April", "27 April", "26 April", "25 April", "24 April", "23 April"]
revenue = [2954222, 2878196, 2804796, 2719896, 2626321, 2544792]


company_data_df = pd.DataFrame({"date": date, "total_revenue": revenue})
company_data = company_data_df.sort_values(by=["total_revenue"])
fig = plt.figure(figsize=(8, 6))
plt.scatter(company_data["date"], company_data["total_revenue"])
plt.plot(company_data["date"], company_data["total_revenue"])
plt.yscale("log")
plt.xlabel("Date")
plt.ylabel("Revenu Total")
plt.title("Evolution du revenu d'une entreprise", fontsize=25)
plt.show()
No description has been provided for this image

Exercice 6¶

In [45]:
# Dictionnaire des matières et couleurs associées 
matieres = {
    'Biologie': '#2ca02c',  
    'Droit et Science Politique': '#d62728',  
    'Economie Gestion': '#ff7f0e',  
    'Informatique': '#1f77b4',  
    'Langues et Litteratures': '#9467bd',  
    'Materiaux, Milieux et Chimie': '#8c564b',  
    'Mathematiques': '#e377c2',  
    'Mathematiques et Informatique': '#7f7f7f',  
    'Medecine': '#bcbd22',  
    'Psychologie': '#17becf',  
    "Science de l'ingenieur": '#ff9896',  
    'Science de la Terre': '#c5b0d5',  
    'Sciences Humaines et Sociales': '#f7b7a3',  
    "Sciences de l'education": '#aec7e8',  
    'Sciences et Techniques des Activités Physiques et Sportives': '#98df8a'  
}


#listes des couleurs
colors = list(matieres.values())

# stackplot
plt.figure(figsize=(15, 6))
plt.stackplot(sout_disc_annee1.index, sout_disc_annee1.T, labels=sout_disc_annee1.columns, alpha=0.8, colors=colors)
plt.xlim(1985, 2018)
plt.grid(True)
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5),title="Disciplines")#legende au centre droit 

# customiser le graphique
plt.title("Évolution quantitative du nombre de thèses soutenues par discipline (1985-2018)", fontsize=16, fontweight='bold')
plt.xlabel("Année")
plt.ylabel("Nombre de thèses soutenues")
plt.tight_layout()

plt.show()
No description has been provided for this image
In [56]:
# Dictionnaire des matières et couleurs associées 
matieres = {
    'Biologie': '#2ca02c',  
    'Droit et Science Politique': '#d62728',  
    'Economie Gestion': '#ff7f0e',  
    'Informatique': '#1f77b4',  
    'Langues et Litteratures': '#9467bd',  
    'Materiaux, Milieux et Chimie': '#8c564b',  
    'Mathematiques': '#e377c2',  
    'Mathematiques et Informatique': '#7f7f7f',  
    'Medecine': '#bcbd22',  
    'Psychologie': '#17becf',  
    "Science de l'ingenieur": '#ff9896',  
    'Science de la Terre': '#c5b0d5',  
    'Sciences Humaines et Sociales': '#f7b7a3',  
    "Sciences de l'education": '#aec7e8',  
    'Sciences et Techniques des Activités Physiques et Sportives': '#98df8a'  
}


#listes des couleurs
colors = list(matieres.values())

# stackplot
plt.figure(figsize=(15, 6))
plt.stackplot(sout_disc_annee1.index, sout_disc_annee1.T, labels=sout_disc_annee1.columns, alpha=0.8, colors=colors)
plt.xlim(1985, 2018)
plt.grid(True)
plt.legend(loc='lower left', bbox_to_anchor=(1, -0.2),title="Disciplines")#legende en bas à droite

# customiser le graphique
plt.title("Évolution quantitative du nombre de thèses soutenues par discipline (1985-2018)", fontsize=16, fontweight='bold')
plt.xlabel("Année")
plt.ylabel("Nombre de thèses soutenues")
plt.tight_layout()

plt.show()
No description has been provided for this image
In [47]:
sns.set_style("white")

y = [9,8,7,6,5,4]
x = [1,2,3,4,5,6]
z= ["Group 1", "Group 2","Group 1", "Group 2","Group 1", "Group 2"]
d = pd.DataFrame({"x": x, "y": y, "Group": z})
palette = {"Group 1": "black", "Group 2": "red"}
legend_positions = ["upper right", "lower left", "lower center", "upper center"] #localisation legende

fig, axes = plt.subplots(2, 2, figsize=(10, 8))#creation du subplot

#boucle pour avoir des graphiques identiques et locaslisations de legendes differentes :
for ax, loc in zip(axes.flat, legend_positions):
    sns.scatterplot(data=d, x="x", y="y", hue="Group", palette=palette, ax=ax)
    ax.legend(title="Groupes", loc=loc)
    ax.set_title(f"Légende: {loc.replace('_', ' ').capitalize()}")
plt.tight_layout()
plt.show()
No description has been provided for this image

Exercice 7 :¶

Nous avions deja créer une palette personnalisée dans l'exercice 1, nous allons essayer maintenant d'utiliser des palettes prédéfinies.

In [48]:
palette = sns.color_palette("tab20", 15)
#  couleurs
colors = palette  # Vous utilisez directement la palette tab20
plt.figure(figsize=(15, 6))
plt.stackplot(sout_disc_annee1.index, sout_disc_annee1.T, labels=sout_disc_annee1.columns, alpha=0.8, colors=palette)
plt.xlim(1985, 2018)
plt.grid(True)
plt.legend(loc='upper left', bbox_to_anchor=(1, 1), title="Disciplines")
plt.title("Évolution quantitative du nombre de thèses soutenues par discipline (1985-2018)", fontsize=16, fontweight='bold')
plt.xlabel("Année")
plt.ylabel("Nombre de thèses soutenues")
plt.tight_layout()
plt.show()
No description has been provided for this image

Exercice 8 :¶

Nous allons inverser les disciplines dans la legende :

In [49]:
palette = sns.color_palette("tab20", 15)
colors = palette  
plt.figure(figsize=(15, 6))
plt.stackplot(sout_disc_annee1.index, sout_disc_annee1.T, labels=sout_disc_annee1.columns, alpha=0.8, colors=palette)
plt.xlim(1985, 2018)
plt.grid(True)

# Modification de l'ordre des disciplines dans la légende sans changer l'ordre des couleurs , attention à bien fixer les couleurs pour ne pas biaiser le graphique
handles, labels = plt.gca().get_legend_handles_labels()
plt.legend(handles[::-1], labels[::-1], loc='upper left', bbox_to_anchor=(1, 1), title="Disciplines")

plt.title("Évolution quantitative du nombre de thèses soutenues par discipline (1985-2018)", fontsize=16, fontweight='bold')
plt.xlabel("Année")
plt.ylabel("Nombre de thèses soutenues")
plt.tight_layout()
plt.show()
No description has been provided for this image
In [50]:
sout_disc_annee
Out[50]:
Année Discipline Nombre de Soutenances
0 1985 Biologie 695
1 1985 Droit et Science Politique 168
2 1985 Economie Gestion 220
3 1985 Informatique 45
4 1985 Langues et Litteratures 268
... ... ... ...
500 2018 Science de l'ingenieur 1396
501 2018 Science de la Terre 471
502 2018 Sciences Humaines et Sociales 1525
503 2018 Sciences de l'education 45
504 2018 Sciences et Techniques des Activités Physiques... 39

505 rows × 3 columns

Exercice 9:¶

In [51]:
sout_disc_annee['Discipline'].unique()
Out[51]:
array(['Biologie', 'Droit et Science Politique', 'Economie Gestion',
       'Informatique', 'Langues et Litteratures',
       'Materiaux, Milieux et Chimie', 'Mathematiques',
       'Mathematiques et Informatique', 'Medecine', 'Psychologie',
       "Science de l'ingenieur", 'Science de la Terre',
       'Sciences Humaines et Sociales', "Sciences de l'education",
       'Sciences et Techniques des Activités Physiques et Sportives'],
      dtype=object)
In [52]:
fig = px.bar(
    sout_disc_annee,
    x='Discipline',
    y='Nombre de Soutenances',
    color='Discipline',
    animation_frame='Année',
    title="Nombre de thèses soutenues par discipline et année",
    labels={"Discipline": "Disciplines", "Nombre de Soutenances": "Nombre de thèses soutenues"},
    category_orders={"Année": sorted(sout_disc_annee['Année'].unique())}  # Trier les années
)

# Mise à jour de la mise en page
fig.update_layout(
    title={
        'text': "Nombre de thèses soutenues par discipline et année (1985-2018)",
        'x': 0.5,
        'xanchor': 'center',
        'y': 0.95,
        'yanchor': 'top'
    },
    xaxis_title="Disciplines",
    yaxis_title="Nombre de thèses soutenues",
    updatemenus=[dict(
        type='buttons',
        showactive=False,
        buttons=[
            dict(label='Play', method='animate', args=[None, {'frame': {'duration': 500, 'redraw': True}, 'fromcurrent': True}]),
            dict(label='Pause', method='animate', args=[[None], {'frame': {'duration': 0, 'redraw': False}, 'mode': 'immediate', 'transition': {'duration': 0}}])
        ]
    )],
    showlegend=True,
    legend=dict(
        title="Discipline",
        x=1.05,  # Décalage de la légende à droite
        xanchor='left',
        y=1,
        yanchor='top',
        font=dict(size=10),  # Réduction de la taille de la police de la légende
        bgcolor='rgba(255, 255, 255, 0.7)',
        bordercolor='Black',
        borderwidth=1
    ),
    margin=dict(l=50, r=150, t=50, b=200),  # Ajustement des marges pour équilibrer l'espace
    width=1000,  # Réduction de la largeur
    height=600,  # Réduction de la hauteur
    xaxis=dict(
        tickangle=45,
        tickfont=dict(size=8),
    ),
    sliders=[
        dict(
            active=0,
            x=0.1,
            len=0.9,
            pad=dict(t=100) 
        )
    ]
)

fig.write_html("nombre_de_theses_soutenues_par_discipline_et_annee(1985-2018).html")

fig.show()
In [53]:
# les facultés ont été rajouté pour ameliorer notre selector.
facultes = {
    "Sciences et Technologies": [
        'Biologie', 'Informatique', 'Mathematiques', 'Mathematiques et Informatique', 'Materiaux, Milieux et Chimie', 'Science de l\'ingenieur', 'Science de la Terre'
    ],
    "Droit et Sciences Sociales": [
        'Droit et Science Politique', 'Sciences Humaines et Sociales', 'Sciences de l\'education'
    ],
    "Sciences de la Santé": [
        'Medecine', 'Psychologie'
    ],
    "Sciences Économiques et Gestion": [
        'Economie Gestion'
    ],
    "Lettres et Langues": [
        'Langues et Litteratures'
    ],
    "Sports et Activités Physiques": [
        'Sciences et Techniques des Activités Physiques et Sportives'
    ]
}

# linker faculté et matiere
discipline_to_faculty = {}
for faculté, disciplines in facultes.items():
    for discipline in disciplines:
        discipline_to_faculty[discipline] = faculté

# Ajouter la colonne 'Faculté' au DataFrame
sout_disc_annee['Faculté'] = sout_disc_annee['Discipline'].map(discipline_to_faculty)

# Afficher le DataFrame mis à jour
sout_disc_annee.head()
Out[53]:
Année Discipline Nombre de Soutenances Faculté
0 1985 Biologie 695 Sciences et Technologies
1 1985 Droit et Science Politique 168 Droit et Sciences Sociales
2 1985 Economie Gestion 220 Sciences Économiques et Gestion
3 1985 Informatique 45 Sciences et Technologies
4 1985 Langues et Litteratures 268 Lettres et Langues
In [54]:
import plotly.express as px

# Création du graphique linéaire avec Plotly
fig = px.line(
    sout_disc_annee,
    x="Année",
    y="Nombre de Soutenances",
    color="Discipline",
    title="Évolution du nombre de thèses soutenues par année",
    labels={"Année": "Année", "Nombre de Soutenances": "Nombre de thèses soutenues"},
    category_orders={"Année": sorted(sout_disc_annee["Année"].unique())},  # Tri des années
)

# Ajout de menus déroulants pour filtrer les disciplines par faculté
faculties = sout_disc_annee["Faculté"].unique()
buttons = []

# Création des boutons pour chaque faculté
for faculté in faculties:
    buttons.append(
        dict(
            label=faculté,
            method="update",
            args=[
                {"visible": [faculté == row_faculté for row_faculté in sout_disc_annee["Faculté"]]},
                {
                    "title": f"Évolution du nombre de thèses soutenues par année ({faculté})",
                },
            ],
        )
    )

# Ajout d'un bouton pour afficher toutes les disciplines
buttons.append(
    dict(
        label="Toutes les disciplines",
        method="update",
        args=[
            {"visible": [True] * len(sout_disc_annee)},  # Tout afficher
            {"title": "Évolution du nombre de thèses soutenues par année (Toutes les disciplines)"},
        ],
    )
)

# Mise à jour de la mise en page
fig.update_layout(
    title={
        "text": "Évolution du nombre de thèses soutenues par année",
        "x": 0.5,
        "xanchor": "center",
    },
    xaxis_title="Année",
    yaxis_title="Nombre de thèses soutenues",
    updatemenus=[
        dict(
            type="dropdown",
            showactive=True,
            buttons=buttons,
            direction="down",
            pad={"r": 10, "t": 10},
            x=0.5,  # Centrer le menu
            xanchor="center",
            y=0.9,  # Positionner le menu sous le titre
            yanchor="top",
        )
    ],
    showlegend=True,
    legend=dict(
        title="Disciplines",
        x=1.05,
        xanchor="left",
        y=1,
        yanchor="top",
        bgcolor="rgba(255, 255, 255, 0.7)",
        bordercolor="Black",
        borderwidth=1,
        font={"size": 10},
    ),
    margin=dict(l=50, r=150, t=70, b=100),
    width=1000,
    height=700,
    xaxis=dict(
        tickangle=45,
        tickfont=dict(size=10),
    ),
    yaxis=dict(
        tickfont=dict(size=10),
    ),
)

# Exportation 
fig.write_html("evolution_du_nombre_de_theses_soutenues_avec_selector_facultes.html")

# Affichage du graphique
fig.show()
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]: